e024aacf18c137cdb61b2dcdfe4739a2c620512f,src/forward_enumeration/table_enumerator/StagedEnumerator.java,StagedEnumerator,enumTable,#EnumContext#number#,30

Before Change


                return decodingToQueries(candidateCollector, ec);
        }

        if (maxDepth == 0)
            return decodingToQueries(candidateCollector, ec);

        //##### Synthesize JOIN
        List<AbstractSummaryTable> stFromLastStage = basicAndAggr;
        List<AbstractSummaryTable> joinSummary;
        for (int i = 1; i <= maxDepth; i ++) {

            joinSummary = EnumerationModules.enumJoin(stFromLastStage, inputSummary);
            summaryTables.addAll(joinSummary);
            stFromLastStage = joinSummary;

            System.out.println("[JOIN] level " + i + " [SymTable]: " + summaryTables.size());

            tryEvalToOutput(stFromLastStage, ec, candidateCollector);
            if (candidateCollector.getAllCandidates().size() > 0) break;
        }

        if (candidateCollector.getAllCandidates().size() > 0)
            return decodingToQueries(candidateCollector, ec);

        //##### Synthesize UNION
        List<AbstractSummaryTable> unionSummary;
        stFromLastStage = inputSummary;
        for (int i = 1; i <= maxDepth-1; i ++) {
            unionSummary = EnumerationModules.enumUnion(stFromLastStage, inputSummary);
            summaryTables.addAll(unionSummary);
            stFromLastStage = unionSummary;
            System.out.println("[UNION] level " + i + " [SymTable]: " + summaryTables.size());

            tryEvalToOutput(stFromLastStage, ec, candidateCollector);
            if (candidateCollector.getAllCandidates().size() > 0) break;
        }

        if (candidateCollector.getAllCandidates().size() > 0)
            return decodingToQueries(candidateCollector, ec);

        //##### Synthesize LEFT-JOIN
        // Try enumerating joining two tables from left-join
        stFromLastStage = inputSummary;
        for (int i = 1; i <= maxDepth-1; i ++) {
            System.out.println("[EnumLeftJoin] level " + i + " [SymTable]: " + summaryTables.size());

            List<AbstractSummaryTable> leftJoinSummary = EnumerationModules.enumLeftJoin(stFromLastStage, inputSummary, ec);
            summaryTables.addAll(leftJoinSummary);
            List<AbstractSummaryTable> rightJoinSummary = EnumerationModules.enumLeftJoin(inputSummary, stFromLastStage, ec);
            summaryTables.addAll(rightJoinSummary);
            tryEvalToOutput(leftJoinSummary, ec, candidateCollector);
            tryEvalToOutput(rightJoinSummary, ec, candidateCollector);
            if (candidateCollector.getAllCandidates().size() > 0) break;
            leftJoinSummary.addAll(rightJoinSummary);
            stFromLastStage = leftJoinSummary;
        }
        // Try enumerating joining two tables from left-join
        stFromLastStage = basicAndAggr;
        for (int i = 1; i <= maxDepth-1; i ++) {

            System.out.println("[EnumLeftJoinWAggr] level " + i + " [SymTable]: " + summaryTables.size());

            List<AbstractSummaryTable> leftJoinSummary = EnumerationModules.enumLeftJoin(stFromLastStage, inputSummary, ec);
            summaryTables.addAll(leftJoinSummary);

            List<AbstractSummaryTable> rightJoinSummary = EnumerationModules.enumLeftJoin(inputSummary, stFromLastStage, ec);
            summaryTables.addAll(rightJoinSummary);

            tryEvalToOutput(leftJoinSummary, ec, candidateCollector);
            tryEvalToOutput(rightJoinSummary, ec, candidateCollector);

            if (candidateCollector.getAllCandidates().size() > 0) break;

            leftJoinSummary.addAll(rightJoinSummary);
            stFromLastStage = leftJoinSummary;
        }

        if (candidateCollector.getAllCandidates().size() > 0)
            return decodingToQueries(candidateCollector, ec);

        //##### Synthesize aggregation on join
        // Enumerate aggregation on joined tables
        List<AbstractSummaryTable> simpleJoinSummary = inputSummary;
        for (int i = 1; i <= maxDepth - 1; i ++) {
            System.out.println("[EnumAggrOnJoin] level " + i + " [SymTable]: " + summaryTables.size());
            simpleJoinSummary.addAll(EnumerationModules.enumJoin(simpleJoinSummary, inputSummary));
        }
        // also include natural join result
        if (maxDepth > 1)
            simpleJoinSummary.add(naturalJoinResult);
        List<AbstractSummaryTable> aggrOnJoinSummary  = EnumerationModules.enumAggregation(simpleJoinSummary, ec);
        if (maxDepth > 2) {
            List<AbstractSummaryTable> joinAfterAggr = EnumerationModules.enumJoin(aggrOnJoinSummary, inputSummary);
            tryEvalToOutput(joinAfterAggr, ec, candidateCollector);
        } else {
            tryEvalToOutput(aggrOnJoinSummary, ec, candidateCollector);
        }

        if (candidateCollector.getAllCandidates().size() > 0)
            return decodingToQueries(candidateCollector, ec);

        //##### Synthesize join with aggregation result
        // Try enumerating by joining two tables from aggregation
        stFromLastStage = basicAndAggr;
        for (int i = 1; i <= maxDepth; i ++) {
            List<AbstractSummaryTable> tmp = EnumerationModules.enumJoin(stFromLastStage, basicAndAggr);

            summaryTables.addAll(tmp);
            stFromLastStage = tmp;
            System.out.println("[EnumJoinOnAggr] level " + i + " [SymTable]: " + summaryTables.size());

            tryEvalToOutput(stFromLastStage, ec, candidateCollector);

            if (candidateCollector.getAllCandidates().size() > 0) break;
        }

        if (candidateCollector.getAllCandidates().size() > 0)
            return decodingToQueries(candidateCollector, ec);

        //##### Synthesizing aggregation on aggregation
        List<AbstractSummaryTable> aggrAggrSummary = EnumerationModules.enumAggregation(aggrSummary, ec);
        for (int i = 1; i <= maxDepth - 1; i ++) {
            List<AbstractSummaryTable> tmp = EnumerationModules.enumJoin(aggrAggrSummary, basicAndAggr);
            tryEvalToOutput(tmp, ec, candidateCollector);
            aggrAggrSummary = tmp;
        }

After Change


public class StagedEnumerator extends AbstractTableEnumerator {

    @Override
    public List<TableNode> enumTable(EnumContext ec, int depth) {

        // this is the list to store all summary tables used in enumeration
        List<AbstractSummaryTable> summaryTables = new ArrayList<>();

        // construct symbolic table for each named table.
        QueryContainer candidateCollector = new QueryContainer(QueryContainer.ContainerType.SummaryTableWBV);

        //##### Synthesize SPJ queries
        // build symbolic table for each input table, and store them in SymTables
        List<AbstractSummaryTable> inputSummary = EnumerationModules.enumFromInputTables(ec, true);
        summaryTables.addAll(inputSummary);
        System.out.println("[Basic]: " + candidateCollector.getMemoizedTables().size() + " [SymTableForInputs]: Intermediate: " + inputSummary.size());

        //##### Synthesize AGGR
        List<AbstractSummaryTable> aggrSummary = EnumerationModules.enumAggregation(inputSummary, ec);
        summaryTables.addAll(aggrSummary);
        System.out.println("[Aggregation]: " + aggrSummary.size() + " [SymTable]: " + summaryTables.size());

        // only contains symbolic table generated from last stage
        //  (here includes those from aggr and input)
        List<AbstractSummaryTable> basicAndAggr = new ArrayList<>();
        basicAndAggr.addAll(summaryTables);

        //##### Synthesize natural join
        // Natural join all input summary tables
        AbstractSummaryTable naturalJoinResult = EnumerationModules.naturalJoinWithUnused(Optional.empty(), inputSummary);

        if (depth == 0) {

            tryEvalToOutput(basicAndAggr, ec, candidateCollector);

            if (GlobalConfig.TRY_NATURAL_JOIN && inputSummary.size() > 1) {
                // try join all tables and infer whether the output table can be obtained in this way
                System.out.println("[NaturalJoin]: " + 1 + " [SymTable]: " + summaryTables.size());
                tryEvalToOutput(naturalJoinResult, ec, candidateCollector);
            }

            if (depth == 0)
                return decodingToQueries(candidateCollector, ec);
        }

        //##### Synthesize JOIN
        List<AbstractSummaryTable> stFromLastStage = basicAndAggr;
        List<AbstractSummaryTable> joinSummary;
        for (int i = 1; i <= depth; i ++) {

            joinSummary = EnumerationModules.enumJoin(stFromLastStage, inputSummary);
            summaryTables.addAll(joinSummary);
            stFromLastStage = joinSummary;

            System.out.println("[JOIN] level " + i + " [SymTable]: " + summaryTables.size());
        }
        // only try eval the queries at this depth
        if (!stFromLastStage.equals(basicAndAggr))
            tryEvalToOutput(stFromLastStage, ec, candidateCollector);
        if (candidateCollector.getAllCandidates().size() > 0)
            return decodingToQueries(candidateCollector, ec);


        //##### Synthesize UNION
        List<AbstractSummaryTable> unionSummary;
        stFromLastStage = inputSummary;
        for (int i = 1; i <= depth-1; i ++) {
            unionSummary = EnumerationModules.enumUnion(stFromLastStage, inputSummary);
            summaryTables.addAll(unionSummary);
            stFromLastStage = unionSummary;
            System.out.println("[UNION] level " + i + " [SymTable]: " + summaryTables.size());
        }
        if (!stFromLastStage.equals(inputSummary))
            tryEvalToOutput(stFromLastStage, ec, candidateCollector);
        if (candidateCollector.getAllCandidates().size() > 0)
            return decodingToQueries(candidateCollector, ec);

        //##### Synthesize LEFT-JOIN
        // Try enumerating joining two tables from left-join
        stFromLastStage = inputSummary;
        for (int i = 1; i <= depth-1; i ++) {
            System.out.println("[EnumLeftJoin] level " + i + " [SymTable]: " + summaryTables.size());

            List<AbstractSummaryTable> leftJoinSummary = EnumerationModules.enumLeftJoin(stFromLastStage, inputSummary, ec);
            summaryTables.addAll(leftJoinSummary);

            List<AbstractSummaryTable> rightJoinSummary = EnumerationModules.enumLeftJoin(inputSummary, stFromLastStage, ec);
            summaryTables.addAll(rightJoinSummary);
            leftJoinSummary.addAll(rightJoinSummary);
            stFromLastStage = leftJoinSummary;
        }
        if (!stFromLastStage.equals(inputSummary)) {
            tryEvalToOutput(stFromLastStage, ec, candidateCollector);
            if (candidateCollector.getAllCandidates().size() > 0)
                return decodingToQueries(candidateCollector, ec);
        }
        // Try enumerating joining two tables from left-join with aggregation
        stFromLastStage = aggrSummary;
        for (int i = 1; i <= depth-1; i ++) {

            System.out.println("[EnumLeftJoinWAggr] level " + i + " [SymTable]: " + summaryTables.size());

            List<AbstractSummaryTable> leftJoinSummary = EnumerationModules.enumLeftJoin(stFromLastStage, inputSummary, ec);
            summaryTables.addAll(leftJoinSummary);

            List<AbstractSummaryTable> rightJoinSummary = EnumerationModules.enumLeftJoin(inputSummary, stFromLastStage, ec);
            summaryTables.addAll(rightJoinSummary);

            leftJoinSummary.addAll(rightJoinSummary);
            stFromLastStage = leftJoinSummary;
        }
        if (! stFromLastStage.equals(aggrSummary)) {
            tryEvalToOutput(stFromLastStage, ec, candidateCollector);
            if (candidateCollector.getAllCandidates().size() > 0)
                return decodingToQueries(candidateCollector, ec);
        }

        if (candidateCollector.getAllCandidates().size() > 0)
            return decodingToQueries(candidateCollector, ec);

        //##### Synthesize aggregation on join
        // Enumerate aggregation on joined tables
        List<AbstractSummaryTable> simpleJoinSummary = inputSummary;
        for (int i = 1; i <= depth - 1; i ++) {
            System.out.println("[EnumAggrOnJoin] level " + i + " [SymTable]: " + summaryTables.size());
            simpleJoinSummary.addAll(EnumerationModules.enumJoin(simpleJoinSummary, inputSummary));
        }
        if (!simpleJoinSummary.equals(inputSummary)) {
            // also include natural join result for depth 2
            if (depth == 2)
                simpleJoinSummary.add(naturalJoinResult);
            List<AbstractSummaryTable> aggrOnJoinSummary = EnumerationModules.enumAggregation(simpleJoinSummary, ec);

            if (depth > 2) {
                List<AbstractSummaryTable> joinAfterAggr = EnumerationModules.enumJoin(aggrOnJoinSummary, inputSummary);
                tryEvalToOutput(joinAfterAggr, ec, candidateCollector);
            } else {
                tryEvalToOutput(aggrOnJoinSummary, ec, candidateCollector);
            }

            if (candidateCollector.getAllCandidates().size() > 0)
                return decodingToQueries(candidateCollector, ec);
        }

        //##### Synthesize join with aggregation result
        // Try enumerating by joining two tables from aggregation
        stFromLastStage = basicAndAggr;
        for (int i = 1; i <= depth; i ++) {
            List<AbstractSummaryTable> tmp = EnumerationModules.enumJoin(stFromLastStage, basicAndAggr);
            summaryTables.addAll(tmp);
            stFromLastStage = tmp;
            System.out.println("[EnumJoinOnAggr] level " + i + " [SymTable]: " + summaryTables.size());
        }
        if (!stFromLastStage.equals(basicAndAggr)) {
            tryEvalToOutput(stFromLastStage, ec, candidateCollector);
            if (candidateCollector.getAllCandidates().size() > 0)
                return decodingToQueries(candidateCollector, ec);
        }

        //##### Synthesizing aggregation on aggregation
        List<AbstractSummaryTable> aggrAggrSummary = EnumerationModules.enumAggregation(aggrSummary, ec);
        for (int i = 1; i <= depth - 1; i ++) {
            List<AbstractSummaryTable> tmp = EnumerationModules.enumJoin(aggrAggrSummary, basicAndAggr);
            aggrAggrSummary = tmp;
        }
        if (depth > 1) tryEvalToOutput(aggrAggrSummary, ec, candidateCollector);

        return decodingToQueries(candidateCollector, ec);
    }